package com.icehand.payment.config;

import io.undertow.Undertow;
import io.undertow.UndertowOptions;
import io.undertow.servlet.api.SecurityConstraint;
import io.undertow.servlet.api.SecurityInfo;
import io.undertow.servlet.api.TransportGuaranteeType;
import io.undertow.servlet.api.WebResourceCollection;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author icehand
 */
@Configuration
public class Http2Configuration {
    @Value("${server.port}")
    private Integer httpsPort;
    @Value("${custom.server.http.port}")
    private Integer httpPort;

    /**
     * 判断站点是否启用http2，在chrome的console输入如下js脚本
     *  (function(){
     *     // 保证这个方法只在支持loadTimes的chrome浏览器下执行
     *     if(window.chrome && typeof chrome.loadTimes === 'function') {
     *         var loadTimes = window.chrome.loadTimes();
     *         var spdy = loadTimes.wasFetchedViaSpdy;
     *         var info = loadTimes.npnNegotiatedProtocol || loadTimes.connectionInfo;
     *         // 就以 「h2」作为判断标识
     *         if(spdy && /^h2/i.test(info)) {
     *             return console.info('本站点使用了HTTP/2');
     *         }
     *     }
     *     console.warn('本站点没有使用HTTP/2');
     * })();
     */
    @Bean
    public ServletWebServerFactory undertowFactory() {
        UndertowServletWebServerFactory undertowFactory = new UndertowServletWebServerFactory();
        undertowFactory.addBuilderCustomizers((Undertow.Builder builder) -> {
            builder.addHttpListener(httpPort, "0.0.0.0");
            // 开启HTTP2
            builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true);
        });
        undertowFactory.addDeploymentInfoCustomizers(deploymentInfo -> {
            // 开启HTTP自动跳转至HTTPS
            deploymentInfo.addSecurityConstraint(new SecurityConstraint()
                    .addWebResourceCollection(new WebResourceCollection().addUrlPattern("/*"))
                    .setTransportGuaranteeType(TransportGuaranteeType.CONFIDENTIAL)
                    .setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.PERMIT))
                    .setConfidentialPortManager(exchange -> httpsPort);
        });
        return undertowFactory;
    }
}
